package com.bbcare.followup.extend.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bbcare.comm.*;
import com.bbcare.followup.extend.dao.ExtendDAO;
import com.bbcare.followup.extend.service.IExtendService;
import com.bbcare.followup.plat.controller.PatientController;
import com.bbcare.followup.plat.entity.FollowQueue;
import com.bbcare.followup.plat.entity.Patient;
import com.bbcare.followup.plat.entity.PatientContentData;
import com.bbcare.followup.plat.service.impl.PatientService;
import com.bbcare.followup.plat.store.ibatis.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;

import javax.annotation.Resource;
import javax.print.DocFlavor;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 扩展业务业务类
 *
 * @author Ace
 */
@Service
public class ExtendServiceImpl implements IExtendService {

    private static final String PATIENT_DATA_CENTER_KEY = "patient_data_center:";

    private final Log logger = LogFactory.getLog(PatientController.class);

    @Autowired
    private IFollowQueueDAO queueDao;

    @Autowired
    private ExtendDAO extendDAO;

    @Autowired
    private IConfCacheDAO IConfCacheDAO;

    @Autowired
    private PatientService patientService;

    @Autowired
    private IPatientTaskContentDAO patientTaskConDao;

    @Autowired
    private IFollowQueueAuthorityDAO followQueueAuthorityDAO;

    @Resource(name = "jedisPool")
    private JedisPool jedisPool;

    // (广三)数据中心患者列表
    @Override
    public Map<String, Object> queryDataCenterPatientList(Map<String, Object> paramMap) throws Exception {
        HashMap<String, Object> argMap = new HashMap<>(paramMap);
        String tenantId = (String) argMap.get("tenantId");
        String fuzzyVar = (String) argMap.get("fuzzyVar");
        // 最终返回Map
        HashMap<String, Object> retMap = new HashMap<>();
        // 查询患者列表List
        List<Map<String, Object>> pqsList = new ArrayList<>();
        retMap.put("total", 0);
        retMap.put("rows", pqsList);

        // 若有服务号码或患者姓名，则先获取患者id串(可能多个)
        List<String> userIdArray = new ArrayList<>();
        int qryUserFlag = 0;
        String phoneNo = (String) argMap.get("phoneNo");
        HashMap<String, Object> qryUserMap = new HashMap<>();
        // 电话号判空
        if (null != phoneNo && !"".equals(phoneNo) && StringUtils.isEmpty(fuzzyVar)) {
            qryUserMap.put("phoneNo", phoneNo);
            qryUserFlag = 1;
        }

        // 根据电话号查询数据
        if (1 == qryUserFlag) {
            List<Patient> ptList = extendDAO.selectByBaseInfo(qryUserMap);
            if (null == ptList || 0 == ptList.size()) {
                logger.warn("无此患者信息...arg==" + qryUserMap.toString());
                return retMap;
            }
            for (Patient patient : ptList) {
                // 后续sql中用in条件处理（这里先不考虑返回结果超过1000个）
                userIdArray.add(patient.getId());
            }
        }

        logger.warn("userIdArray=====" + userIdArray);

        // 根据当前登录账号获取，其可以查看的队列id（权限处理比较复杂，这里先简化）
        String authorId = (String) argMap.get("authorId");
        HashMap<String, Object> qryQueueMap = new HashMap<>();
        qryQueueMap.put("authorId", authorId);
        qryQueueMap.put("queueStatus", Constants.QUEUE_STATUS_NOMAL);// 队列状态正常
        qryQueueMap.put("tenantId", tenantId);
        qryQueueMap.put("queueTypePrivate", Constants.QUEUE_TYPE_PRIVATE);
        qryQueueMap.put("queueTypeTenant", Constants.QUEUE_TYPE_TENANT);
        qryQueueMap.put("queueTypePublic", Constants.QUEUE_TYPE_PUBLIC);

        List<FollowQueue> fqList = null;
        // 1：如果传入队列 则直接用队列查询 2：没有传入队列ID 则根据权限先查询 该用户有哪些队列权限 再查询
        String queueId = (String) argMap.get("queueId");
        String queueName = "";
        if (!StringUtils.isBlank(queueId)) {
            Map<String, Object> queueMap = new HashMap<String, Object>();
            queueMap.put("id", queueId); // 租户id先写死
            fqList = queueDao.selectById(queueMap);
        } else {
            List<Map<String, Object>> lists = IConfCacheDAO.selectAuthorId(qryQueueMap);
            if (lists != null && lists.size() > 0 && !"0".equals((String) argMap.get("showFlag"))) {
                fqList = queueDao.selectQueueIdByparentId(qryQueueMap);
                for (int j = 0; j < fqList.size(); j++) {
                    if (authorId.equals(fqList.get(j).getAuthorId())) {
                        queueName = fqList.get(j).getQueueName();
                    }
                }
            } else {
                fqList = queueDao.selectQueueIdByAuthority(qryQueueMap);
                //根据authorId查询此用户拥有哪些队列的权限
                if (ObjectUtil.isNotEmpty(fqList)){
                    List<String> queueIds = followQueueAuthorityDAO.getDuiLieByAuthorId(authorId);
                    fqList = fqList.stream().filter(item -> {
                        if (queueIds.contains(item.getId())){
                            return true;
                        }else {
                            return false;
                        }
                    }).collect(Collectors.toList());
                }
            }
        }
        argMap.put("queueNameStr", queueName);

        if (null == fqList || 0 == fqList.size()) {
            logger.warn("该账号无可查看到的队列信息...arg==" + qryQueueMap.toString());
            return retMap;
        }

        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(Constants.REDIS_DB_INDEX_CONFIG);
            List<String> queueIdArray = new ArrayList<>();
            for (FollowQueue followQueue : fqList) {
                // 后续sql中用in条件处理（这里先不考虑返回结果超过1000个）
                queueIdArray.add(followQueue.getId());
            }

            // 获取随访患者list
            argMap.put("queueIdIn", queueIdArray);
            if (0 != userIdArray.size()) {
                argMap.put("userIdIn", userIdArray);
            }
            retMap = listAllPatientByCondition(argMap, jedis);
        } catch (JedisConnectionException jex) {
            logger.error("redis连接异常..." + jex.getMessage());
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_REDIS_CONNECT_ERROR, "Redis缓存连接失败!"));
        } finally {
            if (null != jedis) {
                try {
                    jedis.close();
                    logger.warn("close redis connection...");
                } catch (Exception ex) {
                    ex.printStackTrace();
                    throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_REDIS_CONNECT_CLOSE_FAILED,
                            "Redis缓存关闭失败!"));
                }
            }
        }
        return retMap;
    }

    // (广三)全部患者查询(单独封装一个组件)
    public HashMap<String, Object> listAllPatientByCondition(Map<String, Object> mapIn, Jedis jedis) throws Exception {
        HashMap<String, Object> retMap = new HashMap<>();
        HashMap<String, Object> argMap = new HashMap<>(mapIn);
        List<Map<String,Object>> resultList = new ArrayList<>();

        String queueNameStr = (String) argMap.get("queueNameStr");

        int total = 0;
        List<Map<String, Object>> pqsList = new ArrayList<Map<String, Object>>();

        // 诊间扫码查询正常或待审核的患者, modify by DemonLee 2018.03.06
        String systemType = (String) argMap.get("systemType");
        if (StringUtils.isBlank(systemType)) {
            systemType = Constants.CLOUND_SYSTEM_TYPE_FOR_BOTH_FUOUT;
        }
        if (Constants.CLOUND_SYSTEM_TYPE_FOR_FOLLOW.equals(systemType)) {
            // 支撑随访任务和审核状态
            argMap.put("taskExistsFlag", "1");
        }

        // 根据孕周查询
        total = extendDAO.countDataCenterPatient(argMap);
        //港大需求：根据病人号查询。（Modified by Michael Zhu on 2022/06/03）
        int brhTotal = 0;
        List<String> userIdIn = new ArrayList<>();
        Object fuzzyVarObj = mapIn.get("fuzzyVar");
        if (null != fuzzyVarObj) {
            Map<String, Object> paraMap = new HashMap<>();
            final String fuzzyVar = fuzzyVarObj.toString();
            if (!fuzzyVar.isEmpty()) {
                final String answer = fuzzyVar.substring(0, fuzzyVar.length() - 1);
                paraMap.put("questionAnswer", answer);
                List<PatientContentData> brhList = patientTaskConDao.selectBRH(paraMap);
                brhTotal = brhList.size();
                for (PatientContentData pcd : brhList) {
                    userIdIn.add(pcd.getUserId());
                }
            }
        }
        if (total > 0 || brhTotal > 0) {
            pqsList = extendDAO.selectPtQueueList(argMap);
            if (null == pqsList || 0 == pqsList.size()) {
                argMap.remove("fuzzyVar");
                argMap.put("userIdIn", userIdIn);
                pqsList = extendDAO.selectPtQueueList(argMap);
            }
            if (null == pqsList || 0 == pqsList.size()) {
                // 数据被删除或改变了
                total = 0;
            } else {
                HashSet<String> firstNameSet = new HashSet<>();
                Map<String, Object> qryMapIn = new HashMap<>();
                Map<String, Object> qryMapOut = new HashMap<>();

                // 对数据格式进行处理
                pqsList = filterAndExtract(pqsList);
                if (pqsList.size()>0){
                    pqsList = pqsList.stream().sorted(Comparator.comparing(item->{
                        if (ObjectUtil.isEmpty(item.get("scaleAssessStatus"))){
                            item.put("scaleAssessStatus","0");
                        }
                        int scaleAssessStatus = Integer.parseInt((String) item.get("scaleAssessStatus"));
                        return scaleAssessStatus;
                    }, Comparator.reverseOrder())).collect(Collectors.toList());
                }
                total = pqsList.size();

                // 提前进行手动分页
                int start = (int) argMap.get("start");
                int end = (int) argMap.get("end");

                for (int i = start; i <= (end >= pqsList.size()? pqsList.size() -1 : end); i++) {
                    Map<String, Object> pqsMap = pqsList.get(i);

                    String firstName = (String) pqsMap.get("FirstName");
                    firstNameSet.add(firstName);

                    // 获取队列名称及专案名称
                    List<Map<String,Object>> userInfo = (List<Map<String, Object>>) pqsMap.get("userInfo");
                    for (Map<String, Object> map : userInfo) {
                        qryMapIn.clear();
                        qryMapIn.put("queueId", map.get("followQueueId"));
                        qryMapOut = patientService.getQueueName(qryMapIn, jedis);
                        map.put("followQueueName",qryMapOut.get("queueName"));
                        qryMapIn.put("schemeId", map.get("schemeId"));
                        qryMapOut = patientService.getSchemeName(qryMapIn, jedis);
                        map.put("schemeName", qryMapOut.get("schemeName"));
                    }

                    List<FollowQueue> flq = queueDao.selectById(qryMapIn);
                    if (!StringUtils.isBlank(queueNameStr) && !queueNameStr.equals(qryMapOut.get("queueName"))
                            && Constants.LOST_REASON_TYPE_PRIVATE.equals(flq.get(0).getQueueType())) {
                        pqsMap.put("unchecked", "1");
                    } else {
                        pqsMap.put("unchecked", "0");
                    }

                    qryMapIn.put("userId", (String) pqsMap.get("patientId"));
                    // 微信月度评估兼容返回出生体重
                    List<PatientContentData> lists = patientTaskConDao.listCntDataByUserIdAndAcceptPrivate(qryMapIn);
                    if (!CollectionUtils.isEmpty(lists)) {
                        for (int j = 0; j < lists.size(); j++) {
                            if (Constants.QUESTION_ID_FOR_WEIGHT.equals(lists.get(j).getQuestionId())) {
                                pqsMap.put("weight", lists.get(j).getQuestionAnswer());
                            } else if (Constants.QUESTION_ID_FOR_LAST_MENSTRUATION_DATE.equals(lists.get(j).getQuestionId())) {
                                pqsMap.put(Constants.QUESTION_ID_FOR_LAST_MENSTRUATION_DATE, lists.get(j).getQuestionAnswer());
                            }
                        }
                    }

                    //pqsMap.put("createTime", DateUtil.getTimeStampDay(pqsMap.get("createTime").toString()));
                    // 年龄
                    Object birthdayObj = (Object) pqsMap.get("birthday");
                    if (null != birthdayObj) {
                        String birthdayStr = String.valueOf(birthdayObj);
                        if (!StringUtils.isEmpty("" + pqsMap.get("pregnancyDay"))
                                && StringUtils.isNotBlank(birthdayStr)) {
                            String pregnancy = "" + pqsMap.get("pregnancyDay");
                            long correctAge = ToolUtils.getCorrect(String.valueOf(pqsMap.get("birthday")),
                                    Integer.parseInt(pregnancy));

                            Date date = new Date(correctAge);
                            pqsMap.put("age", ToolUtils.getAgeByBirthday(DateUtil.getDate_8(date)));
                            pqsMap.put("pregnancyWeek",
                                    ToolUtils.getPregnancyStr(Integer.parseInt("" + pqsMap.get("pregnancyDay"))));
                        } else if (StringUtils.isNotBlank(birthdayStr)) {
                            // 孕周为空则按正常年龄算
                            pqsMap.put("age", ToolUtils.getAgeByBirthday("" + pqsMap.get("birthday")));
                        } else {
                            pqsMap.put("age", "");
                        }
                    } else {
                        pqsMap.put("age", "");
                    }
                    //男女判断
                    String gender = pqsMap.get("gender").toString();
                    if ("男".equals(gender) || "N".equals(gender)) {
                        pqsMap.put("gender2", "男");
                    } else if (StringUtils.isNotEmpty(gender)) {
                        pqsMap.put("gender2", "女");
                    }
                    //转诊功能增加字段
                    String fileNo = "";
                    if (null != pqsMap.get("fileNo")) {
                        fileNo = pqsMap.get("fileNo").toString();
                        pqsMap.put("fileNo", fileNo);
                    }
                    resultList.add(pqsMap);
                }
                StringBuilder firstNameValue = new StringBuilder();
                for (String s : firstNameSet) {
                    firstNameValue.append(s);
                    firstNameValue.append(",");
                }
                retMap.put("FirstName", firstNameValue.substring(0, firstNameValue.length() - 1));
            }
        }

        retMap.put("total", total);
        retMap.put("rows", resultList);

        return retMap;
    }

    // (广三)获取读写权限
    @Override
    public Map<String, Object> getReadWriteRole(String args) {
        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(args);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        String accountId = jsonData.getString("accountId");
        if (StringUtils.isBlank(accountId)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "accountId不能为空!");
        }

        Map<String, Object> role = extendDAO.selectRoleByAccountId(accountId);
        if (role == null) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "无该用户信息!");
        }

        if ("readOnly".equals(role.get("role"))) {
            role.put("role", "0");
        } else {
            role.put("role", "1");
        }
        return role;
    }

    // 过滤和合并patient数据
    public List<Map<String, Object>> filterAndExtract(List<Map<String, Object>> list) {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();

        for (Map<String, Object> patient : list) {
            // 储存每个队列数据
            Map<String, Object> userInfoMap = new HashMap<>();

            // 获取到每一个患者id
            String patientId = (String) patient.get("patientId");

            String patientSchemeId = (String)patient.get("patientSchemeId");

            String followQueueId = (String)patient.get("followQueueId");
            if (followQueueId.contains("naocuzhong")){
                Map<String, Object> map = new HashMap<>();
                map.put("patientId",patientId);
                map.put("patientSchemeId",patientSchemeId);
                //根据患者id查询患者最近一次随访内容
                //List<PatientContentData> patientContentDataList = patientService.queryPatientRecentlyFollowRecord(map);
                //if (patientContentDataList!=null && patientContentDataList.size()>0){
                //    patientContentDataList.stream().forEach(item->{
                //        if (item.getQuestionId().equals("ncz_nczfxpj")){
                //            String answer = item.getQuestionAnswer();
                //            if (answer.contains("低危")){
                //                patient.put("nczfxpj","低危");
                //                return;
                //            }
                //            if (answer.contains("中危")){
                //                patient.put("nczfxpj","中危");
                //                return;
                //            }
                //            if (answer.contains("高危")){
                //                patient.put("nczfxpj","高危");
                //                return;
                //            }
                //        }
                //    });
                //}
            }

            // 获取每一个患者的队列信息
            userInfoMap.put("patientSchemeId", patientSchemeId);
            userInfoMap.put("schemeId", patient.get("schemeId"));
            userInfoMap.put("followQueueId", patient.get("followQueueId"));

            // 删除重复的key
            patient.remove("patientSchemeId");
            patient.remove("schemeId");
            patient.remove("followQueueId");

            Map<String, Object> result = resultMap.get(patientId);
            if (result == null) {
                List<Map<String, Object>> userInfoList = new ArrayList<>();
                userInfoList.add(userInfoMap);

                result = new HashMap<>(patient);
                result.put("userInfo", userInfoList);

                resultMap.put(patientId, result);
            } else {
                List<Map<String, Object>> userInfo = (List<Map<String, Object>>) result.get("userInfo");
                userInfo.add(userInfoMap);
            }
        }

        list.clear();
        list.addAll(resultMap.values());
        return list;
    }
}
